public class SystemController
{
	DBOps dbHandler;
	//User user;
	CourseDirectory courseDir;
	String userLogin;
	int userId;
	int adminStatus;
	int currentCid;//the course being taken/previewed by user
	int [] histogram;//each element is a separate bin
	//String userRequest; 
	//Course course; 
	
	/*The system controller class collaborates with a number of classes to provide proper functionality within the system.  
	 *The system controller gets course information from the course directory.  
	 *Questions are obtained from the question class and then added to the survey via the survey class.  
	 *The system controller also creates response classes using student responses.  
	 *Survey results objects are created by the system controller which 
	 *	first accesses the compiled results from the completed surveys class, 
	 *	these results are then used by the system controller to generate the an instance of the survey results class.*/
	 
	/* The system controller class should also contain an instance of the database handler class DBOps.
	 * The database handler class executes queries and returns results to the system controller which then 
	 * handles those results in the appropriate way or returns those results to the GUIMaster class.*/
	
	SystemController()
	{
		dbHandler = new DBOps();
		courseDir = new CourseDirectory();
		adminStatus = 0;
		currentCid = -1;
		histogram = new int [5];
		clearHistogram();
	}
	
	boolean submitPasswordChange (String oldPassword, String newPassword)
	{
		boolean changeSuccessful = false;
		System.out.println(userLogin + " " + oldPassword + " " + newPassword);
		if (dbHandler.changePassword(userLogin, oldPassword, newPassword) == 1)
			changeSuccessful = true;
			
		return changeSuccessful;
	}
	
	//takes in a user supplied login and password and 
	// checks whether the combination is stored in the database
	boolean verifyLogin (String login, String password)
	{
		boolean loginStatus = false;
		
		//call DBOps function to query for login and password
		//if (  password.equals(dbHandler.retrievePassword(login))  )
		if (dbHandler.validateUser(login, password) == 1 )
		{
			loginStatus = true;
			userLogin = new String(login);
			
			//store the userid and adminstatus for convenience
			userId = dbHandler.getUserID(userLogin);
			adminStatus = dbHandler.getAdminStatus(userLogin);
			
			System.out.println(adminStatus);
			//load up the courses and survey info
			if (adminStatus == 0)
				buildCourseDirectory();
		}
		
		return loginStatus;//loginStatus;
	}
	
	//with the userid known, the courses that are associated with that
	// user can be loaded into a course directory
	void buildCourseDirectory()
	{
		int i, j;
		Course courses[];
		courses = dbHandler.getCourses(userId);
		
		Survey s;// = new Survey();
		
		for (j = 0; j < courses.length; j++)
		{
			s = new Survey();
			Question [] q;
			q = dbHandler.getSurveyQuestions(courses[j].cid);
		
			//set all questions in survey
			for (i = 0; i < q.length; i++)
				s.setQuestion(q[i]);
		
			//store the survey in the curr course
			courses[j].storeSurvey(s);
			s = null;
		}
		
		//set courses in coursedirectory
		courseDir.setCourses(courses);
		
		//set course names in course GUI
		GUIMaster.getInstance().courseSelectGUI.setCourseNames();
	}
	
	void submitResponses(int cid, Response [] responses)
	{
		if(dbHandler.submitSurvey(userId, cid, responses) == 1)
			System.out.println("Submit survey success!");
		else
			System.out.println("Submit survey failed!");
	}
			
	void deleteQuestion(int qid)
	{
		if(dbHandler.removeSurveyQuestion(qid) == 1)
			System.out.println("Remove question success!");
		else
			System.out.println("Remove question fail!");
	}
	/*public String [] getCourseNames()
	{
		Course [] c = courseDir.getCourses();
		String [] courseNames = null;
		if (c.length > 0)
		{
			int i;
			courseNames = new String [c.length];
			for(i = 0; i < c.length; i++)
			{
				courseNames[i] = new String(c[i].getDept() + " " + c[i].getNumber());
			}
		}
		else
			System.out.println("Directory is empty");
			
		return courseNames;
	}*/
	//used to load the questions for a particular survey onto the screen
	//possibly done with labels
	//args are the course survey being taken, and an index for the particular question being loaded
	//it is up to the GUIMaster class to display the question and answers in the appropriate manner
	// next to the right radio buttons etc...
	//maybe make loadquestion subservient to a loadsurvey function
	/*Questions loadQuestion(course, index)
	{
		//load the correct survey into a survey object
		Survey survey = courseDir.getCourse(course).getSurvey();
		
		//retrieve the question from the survey using the supplied index
		survey.getQuestion(index);
		
		//should the question object be returned or just an array of strings it possesses?
		// if you return the strings it has, that's practically the whole object,
		// you might as well return the Question itself.
	}*/
	
	//again, it makes more sense to wrap up the question itself and its possible
	// responses inside a Question class and pass that, than submit everything separately
	/*submitMultipleChoiceQuestion(Question)
	{
		dbHandler.submit(Question);
		
	}*/
	
	
	
	/*
	 //The storeSurveyResponses method adds all responses to response objects.  
	//The method does not take any arguments and does not return anything.  
	//All work is done within the method.
	void storeSurveyResponses()
	{
		
	}
	
	*/
//	The addSurveyQuestion method takes a single argument, q, 
	// of type question and adds the question to the course survey.  
	//The method has return type void as it does not return anything.
	void addSurveyQuestion(Question q)
	{	
		//add the new question to the appropriate survey 
		// so that when it is reloaded it appears on the survey
		Course c = courseDir.getCourse(currentCid);
		Survey s = c.getSurvey();
		s.setQuestion(q);
		System.out.println("Adding survey question...");
		//add survey question to database as well
		if(dbHandler.addSurveyQuestion(userId, currentCid, q) == 1)
			System.out.println("Add question is a success!");
		else
			System.out.println("Add question failed!");
		
	}
	
	void reset()
	{
		//zeroize & reallocate for next user
		courseDir = null;
		courseDir = new CourseDirectory();
		
		//zeroize
		userLogin = null;
		userId = -1;
		adminStatus = 0;
		currentCid = -1;
		clearHistogram();
		
	}
	
	Result [] prepareResults(int cid)
	{
		Response [] r;
		Response [] specificResp;
		Result [] results;
		Result [] truncatedResults; //like results but has as many elements as results and no extra
		Question [] questions;
		String [] oeResults;
		int i,j,mc, oe, tr;
		//get all responses for survey  
		r = dbHandler.getSurveyResults(cid);
		questions = dbHandler.getSurveyQuestions(cid);
		results = new Result [questions.length];
		
		//cycle through all responses
		int currentQid;
		for (i = 0, mc = 0, oe = 0; i < results.length; i++)
		{
		// 1 iteration of this outer loop should make 1 result
		
			//create new array with responses to this 1 question
			currentQid = questions[i].getQid();
			
			//this new array should have responses to a particular question
			specificResp = pullResponseSet(r, currentQid);
			if (specificResp.length > 0)
			{
				if (questions[i].getType() == 2)//fill one mc result
				{
					results[i] = processAnswersToOneQuestion(specificResp, questions[i]);
					//System.out.println(results[i].getContent());
					mc++;
				}
				else if (questions[i].getType() == 3)//fill one oe result
				{
					oeResults = new String [specificResp.length];
					for(j = 0; j < specificResp.length; j++)
					{
						oeResults[j] = specificResp[j].resp;	
					}
					results[i] = new Result(questions[i].getContent(), questions[i].getType(), oeResults);
					oe++;
					oeResults = null;
				}
			}
			specificResp = null;
			
		}
		
		for (i = 0; i < results.length; i++)
		{
			if (results[i] != null)
			{
				System.out.println(i + " " + results[i].getContent());
			}
		}
		
		//copy pulledSet to truncated array
		truncatedResults = new Result [mc + oe];
		
		for(i = 0, tr = 0; i < results.length; i++)
		{
			if (results[i] != null)
			{
				truncatedResults[tr] = results[i];
				tr++;
			}				
		}
		
		return truncatedResults;
	}
	
	Response [] pullResponseSet(Response [] masterList, int qid)
	{
		int j = 0;
		int i;
		Response [] pulledSet = new Response [masterList.length];//worse case scenario
		Response [] returnArray;
		for(i = 0; i < masterList.length; i++)
		{
			if (masterList[i].id == qid)
			{
				pulledSet[j] = masterList[i];
				j++;
			}
		}
		//copy pulledSet to truncated array
		returnArray = new Response [j];
		
		for(i = 0; i < returnArray.length; i++)
		{
			returnArray[i] = pulledSet[i];
		}
		
		return returnArray;
	}
	
	
	Question searchQuestions(Question [] questions, int qid)
	{
		int i;
		//search array for correct course
		for (i = 0; i < questions.length ;i++)
		{
			if(qid == questions[i].getQid())
				return questions[i];
		}
		System.out.println("Question not found!");
		return null;
	}
	
	Result processAnswersToOneQuestion(Response [] r, Question q)
	{
		int i, j, end, responsesPerQuestion;
		String currResp;
		String [] answers = q.getPossibleAns();	
		double [] percentages = new double[histogram.length]; 
		Result res;
		//System.out.println(r.length);
		for (i = 0; i < r.length; i++)
		{
		//1 iteration is one response to a particular question
		
			//extract response strings
			//create histogram of responses
			//System.out.println(r[i].resp);
			currResp = r[i].resp;
			histogramData(currResp, answers);
			
		}
		//create result object based on tallied responses and question data
		//make percentage results from number of responses provided and histogram data
		for(i = 0; i < histogram.length; i++)
		{
			percentages[i] = histogram[i] / (double)r.length;

			//format the percentage properly
			percentages[i] = percentages[i] * 100000 + 5; //round to 2 decimal places
			percentages[i] /= 10;
			int temp = (int) (percentages[i]);
			percentages[i] = temp / (double) 100.00;
			//System.out.println(percentages[i]);
		}
		res = new Result(q.getContent(), q.getType(), 
			q.getPossibleAns(), percentages);
		clearHistogram();
			
		return res;
	}
	
	void histogramData(String r, String [] answers)
	{
		for (int j = 0 ; j < answers.length; j++)
		{
			if (r.equals(answers[j]))
			{
				histogram[j]++;
				j = answers.length;//break out of loop
			}
		}
	}
			
	void clearHistogram()
	{
		for(int i = 0; i < histogram.length; i++)
			histogram[i] = 0;
	}
	
	void addUser(User u)
	{
		dbHandler.add_user(u.firstname, u.username, u.password);
		int newId = dbHandler.getUserID(u.username);
		for (int i = 0; i < u.courses.length; i++)
		{
			dbHandler.add_user_course_link(newId, u.courses[i], 1, "N");
		}
		System.out.print("User added successfully");
	}
	
	void addMultipleUsers(User [] u)
	{
		for (int i = 0; i < u.length; i++)
		{
			addUser(u[i]);
		}
	}
	
//	The generateSurveyResults method takes an array of type string as an argument and returns nothing. 
	//The array contains the compiled results.  
	//These results are used to create a survey results object. 
	/*void generateSurveyResults(String compiledResults[])
	{
		
	}*/
	
	/*
//	The getSelectedCourse method takes no arguments and returns a value of type course.  
	//The returned value contains the course object of the currently selected course.
	 
	
	Course getSelectedCourse()
	{
		return course;
	}
	
//	The updateUserRequest method takes an argument of type string and returns nothing.  
	//The argument is set to the userRequest variable by the method.
	void updateUserRequest(String req)
	{
		userRequest = req;
	}
	
	
//	The getUserRequest method takes no input arguments and returns an object of type string.  
	//The value of the userRequest variable is returned by the method.
	String getUserRequest()
	{
		return userRequest;
	}*/
}
